#include "patchmethod.h"

PatchMethod::PatchMethod(QMap<QListWidgetItem *, MdlInfo *> *MdlInfoMap, QDialog *parent):QDialog(parent)
{
    this->setWindowIcon(QIcon(":/QSS/image/Window_Icon.png"));
    this->setWindowTitle(tr("Configuration data conversion method"));
    QDesktopWidget* desktopWidget = QApplication::desktop();
    //得到客户区矩形
    clientRect = desktopWidget->availableGeometry();
    this->setModal(true);
    Qt::WindowFlags flags=Qt::Widget;
    //flags |=Qt::WindowMinimizeButtonHint;
    this->setWindowFlags(flags);
    this->setMouseTracking(true);
    this->scene =new mScene();
    this->MdlInfoMap = MdlInfoMap;

}
void PatchMethod::initUI(QList<CState *> * CurrentStateList){
    if(!readConversionMethods()){
        return;
    }

    MainLayout=new QHBoxLayout();

    //ModelPreview
    this->ViewScrollArea = new QScrollArea();
    QGridLayout *ViewArea = new QGridLayout();
    ViewArea->setMargin(0);
    ViewScrollArea->setLayout(ViewArea);
    ViewArea->addWidget(new QGraphicsView(this->scene));
    MainLayout->addWidget(this->ViewScrollArea,1);


    scrollArea = new QScrollArea;
    eventMap = new QMap<int,oneEventFrame *>();
    //scrollArea->setBackgroundRole(QPalette::Dark);
    scrollArea->setSizePolicy(
                QSizePolicy::Expanding,QSizePolicy::Expanding);
    scrollArea->setWidgetResizable(true);
    this->setMinimumSize(clientRect.width()*0.6,clientRect.height()*0.6); //最小宽高设置
   // this->showMaximized();
//    scrollArea->setMaximumSize(clientRect.width()*0.7,clientRect.height()*0.7); //最大宽高设置
    this->setLayout(MainLayout);
    MainLayout->addWidget(scrollArea,1);

    int ResHeight = 1;
    int NoResHeight = 1;


    QWidget *inScrollArea=new QWidget();
    QGridLayout *inWidgetLayout=new QGridLayout();
    inScrollArea->setLayout(inWidgetLayout);




    QGroupBox *resEventFrame=new QGroupBox(tr("Response"));
    QVBoxLayout *resEventLayout = new QVBoxLayout();
    resEventFrame->setLayout(resEventLayout);

    QGroupBox *noResEventFrame = new QGroupBox("NoResponse");
    QVBoxLayout *NoResEventLayout = new QVBoxLayout();
    noResEventFrame->setLayout(NoResEventLayout);

    scrollArea->setWidget(inScrollArea);
    int EventIndex=0;


    this->mStateMapList=new QMap<QString,QList<oneEventFrame *>*>();
    for(int i=0;i<CurrentStateList->length();i++){
        CState *cState=new CState();
        //get Event count;

        cState=CurrentStateList->at(i);
        ResHeight = cState->getResEventCount();
        NoResHeight =cState->getNoResEventCount();
        OneEventList = new QList<oneEventFrame *>();
        for(int j=0;j<cState->getCount();j++){
            if(cState->getEvent(j)->getEventType()=="response"){
               oneEventFrame* ResOneEvent=new oneEventFrame(resEventLayout,mDirPath,
                                           cState->getEvent(j)->getEventName(), cState->getEvent(j)->getEventType(),this->mConversionMethods,EventIndex);
                eventMap->insert(EventIndex,ResOneEvent);
                OneEventList->append(ResOneEvent);
                EventIndex+=1;
            }else if(cState->getEvent(j)->getEventType()=="noresponse"){
                 oneEventFrame* NoResOneEvent=new oneEventFrame(NoResEventLayout,mDirPath,
                                                                cState->getEvent(j)->getEventName(), cState->getEvent(j)->getEventType(),this->mConversionMethods,EventIndex);
                eventMap->insert(EventIndex,NoResOneEvent);
                OneEventList->append(NoResOneEvent);
                EventIndex+=1;
            }
        }
        this->mStateMapList->insert(cState->getStateName(),OneEventList);
    }

    inWidgetLayout->addWidget(resEventFrame,0,0,1,1);
    inWidgetLayout->addWidget(noResEventFrame,1,0,1,1);
    inWidgetLayout->setSpacing(20);
    inWidgetLayout->setMargin(40); //control distance with outside line.
    int btnHeight=NoResHeight+ResHeight;

    QGridLayout *btnLayout=new QGridLayout();
    ConfirmButton =new QPushButton(tr("Confirm"));
    CancelButton  = new QPushButton(tr("cancel"));
    btnLayout->addWidget(ConfirmButton,0,0,1,1);
    btnLayout->addWidget(CancelButton,0,1,1,1);
    inWidgetLayout->addLayout(btnLayout,btnHeight,0,1,1,Qt::AlignCenter);




    connect(CancelButton,SIGNAL(clicked(bool)),this,SLOT(on_cancle_clicked()));

    connect(ConfirmButton,SIGNAL(clicked(bool)),this,SLOT(on_confirm_clicked()));

    connect(this->scene,SIGNAL(on_ModelState_doubleClicked(CState*)),this,SLOT(StateChange(CState*)));



}
void PatchMethod::setMethod(QString EventName,QString MethodFilePath,QString DataRelativePath){
    if(EventName.isEmpty()||MethodFilePath.isEmpty()||DataRelativePath.isEmpty()) return ;
    for(int i=0;i<OneEventList->count();i++){
        if(EventName ==OneEventList->at(i)->getEventName()){
           OneEventList->at(i)->setProperties(MethodFilePath,DataRelativePath);
        }
    }
}

void PatchMethod::on_cancle_clicked(){
     this->reject();

}
void PatchMethod::on_confirm_clicked(){
    DCCInfoMap=new QMap<int,DCCInfo *>();
    QMapIterator<int,oneEventFrame *> InfoMap(*eventMap);
     while (InfoMap.hasNext()) {
         InfoMap.next();
         oneEventFrame *oneEvent=InfoMap.value();
         DCCInfo *dCCInfo=new DCCInfo(oneEvent->getEventName(),
                                      oneEvent->getEventType(),
                                      oneEvent->getMethodFoldPath(),
                                      oneEvent->getMethodName(),
                                      oneEvent->getFileRelativePath()
                                    );

        DCCInfoMap->insert(InfoMap.key(),dCCInfo);
     }
     emit SendDCCInfo(this->DCCInfoMap);
    this->accept();
}


bool PatchMethod::readConversionMethods(){
    this->mConversionMethods = new QList<CMethodsInfo *>();
    QDir  ProjectDir(QApplication::applicationDirPath());
    mDirPath = ProjectDir.absolutePath();
    //ProjectDir.cdUp();
    QString DirPath=mDirPath+"/config/project.xml";
    if(!mGet_setInfo->readMethods(mDirPath,DirPath,this->mConversionMethods)){
        return false;
    }
    return true;
}

void PatchMethod::ShowCustomScene(QListWidgetItem *item){
    this->scene->clear();
    QList<CState *> *StateList=  MdlInfoMap->value(item)->getStateInfo();
    if(StateList==NULL){
        qWarning()<<"StateList in PatchMethod::ShowCustomScene is null."<<endl;
        return;
    }
    this->scene->addAllInfo(StateList);
    int ProcessX=0;
    int ProcessY=0;
    bool LeftToRight = true;
    this->scene->addProcessItem(QString::number(0),"Start",25,0);
    for(int i=0;i<StateList->size();i++){
        QPointF ProcessPoint= PatchMethod::getXY(ProcessX,ProcessY,this->ViewScrollArea->width(),LeftToRight);
        ProcessX = ProcessPoint.x();
        ProcessY = ProcessPoint.y();
        this->scene->addProcessItem(QString::number(i+1),StateList->at(i)->getStateName(),ProcessX,ProcessY);
        this->scene->addArrowItem(QString::number(i),QString::number(i+1));
        if(i+1==StateList->size()){
            QPointF ProcessPoint= PatchMethod::getXY(ProcessX,ProcessY,this->ViewScrollArea->width(),LeftToRight);
            ProcessX = ProcessPoint.x();
            ProcessY = ProcessPoint.y();
            this->scene->addProcessItem(QString::number(i+2),"End",ProcessX,ProcessY);
            this->scene->addArrowItem(QString::number(i+1),QString::number(i+2));
        }
    }
}

QPointF PatchMethod::getXY(int X,int Y,int XLength,bool &LeftToRight){

    int ProcessX=X;
    int ProcessY=Y;
    if(LeftToRight){
        if(ProcessX<XLength){
            ProcessX +=160;
        }else{
            LeftToRight=false;
            ProcessY+=160;
        }
    }else{
        if(ProcessX>50){
             ProcessX -=160;
        }else{
            LeftToRight=true;
            ProcessY+=160;
        }
    }
    return QPointF(ProcessX,ProcessY);
}

void PatchMethod::StateChange(CState *CurrentState){
   QMap<QString,QList<oneEventFrame *>*>::iterator i;
    for (i = this->mStateMapList->begin(); i != this->mStateMapList->end(); ++i)
        if(i.key()==CurrentState->getStateName()){
            for(int j=0;j<i.value()->size();j++){
                i.value()->at(j)->oneFrame->setVisible(true);
            }
        }else{
            for(int j=0;j<i.value()->size();j++){
                i.value()->at(j)->oneFrame->setVisible(false);
            }
        }
}

